package com.shunli.cterminal.strategy;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.examples.core.exception.ServiceException;
import com.shunli.cterminal.enums.ConditionTypeEnum;
import com.shunli.cterminal.enums.TimeTypeEnum;
import com.shunli.cterminal.model.code.CterminalResultCode;
import com.shunli.cterminal.model.dto.PolicyTimeJsonDTO;
import com.shunli.cterminal.model.dto.TrafficPolicyStrategyDTO;
import com.shunli.cterminal.model.res.SystemTrafficPolicyVO;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 时间策略
 * </p>
 *
 * @author daodao
 * @since 2025-04-25 15:19
 */
@Component
public class TimeStrategy implements Strategy {

    /**
     * 获取条件类型  ConditionTypeEnum
     *
     * @return
     */
    @Override
    public String getConditionTypeEnum() {
        return ConditionTypeEnum.AND.getCode();
    }

    /**
     * 执行策略 结果
     *
     * @param beforeResult 上一个规则过滤后的结果 价格
     * @return String
     */
    @Override
    public Set<SystemTrafficPolicyVO> parse(Set<SystemTrafficPolicyVO> beforeResult, TrafficPolicyStrategyDTO trafficPolicyStrategyDTO) {
        if (CollectionUtil.isEmpty(beforeResult)) {
            return null;
        }
        beforeResult = beforeResult.stream()
                .filter(systemTrafficPolicyVO -> {
                    PolicyTimeJsonDTO policyTimeJsonDTO = systemTrafficPolicyVO.getTimeJsonDTO();
                    if (ObjectUtil.hasNull(policyTimeJsonDTO, policyTimeJsonDTO.getTimeType()) || CollectionUtil.isEmpty(policyTimeJsonDTO.getTimeInterval())) {
                        return false;
                    }

                    if (StrUtil.equals(TimeTypeEnum.DATA_TIME.getCode(), policyTimeJsonDTO.getTimeType())) {
                        return checkDataTime(policyTimeJsonDTO.getTimeInterval(), trafficPolicyStrategyDTO);
                    } else if (StrUtil.equals(TimeTypeEnum.DATA.getCode(), policyTimeJsonDTO.getTimeType())) {
                        return checkData(policyTimeJsonDTO.getTimeInterval(), trafficPolicyStrategyDTO);
                    } else if (StrUtil.equals(TimeTypeEnum.HOLIDAYS.getCode(), policyTimeJsonDTO.getTimeType())) {
                        // 节假日暂无校验
                        throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
                    } else if (StrUtil.equals(TimeTypeEnum.WEEK.getCode(), policyTimeJsonDTO.getTimeType())) {
                        return checkWeek(policyTimeJsonDTO.getTimeInterval(), trafficPolicyStrategyDTO);
                    }
                    return false;
                })
                .collect(Collectors.toSet());
        return beforeResult;
    }

    public boolean checkDataTime(List<PolicyTimeJsonDTO.PolicyTimeInterval> policyTimeJsonDTO, TrafficPolicyStrategyDTO trafficPolicyStrategyDTO) {
        LocalTime crateTime = trafficPolicyStrategyDTO.getCreateOrderTime().toLocalTime();

        for (PolicyTimeJsonDTO.PolicyTimeInterval policyTimeInterval : policyTimeJsonDTO) {
            LocalTime targetStartTime = LocalTime.parse(policyTimeInterval.getStartInterval());
            LocalTime targetEndTime = LocalTime.parse(policyTimeInterval.getEndInterval());
            boolean isInRangeStartTime = (targetStartTime.isBefore(crateTime) || targetStartTime.equals(crateTime)) && targetEndTime.isAfter(crateTime);
            if (isInRangeStartTime) {
                return true;
            }
        }
        return false;
    }

    public boolean checkData(List<PolicyTimeJsonDTO.PolicyTimeInterval> policyTimeJsonDTO, TrafficPolicyStrategyDTO trafficPolicyStrategyDTO) {
        LocalDate crateDate = trafficPolicyStrategyDTO.getCreateOrderTime().toLocalDate();
        for (PolicyTimeJsonDTO.PolicyTimeInterval policyTimeInterval : policyTimeJsonDTO) {
            LocalDate targetStartTime = LocalDate.parse(policyTimeInterval.getStartInterval());
            LocalDate targetEndTime = LocalDate.parse(policyTimeInterval.getEndInterval());
            boolean isInRangeStartTime = ((targetStartTime.isBefore(crateDate) || targetStartTime.isEqual(crateDate)) && targetEndTime.isAfter(crateDate));
            if (isInRangeStartTime) {
                return true;
            }
        }
        return false;
    }


    public boolean checkWeek(List<PolicyTimeJsonDTO.PolicyTimeInterval> policyTimeJsonDTO, TrafficPolicyStrategyDTO trafficPolicyStrategyDTO) {
        LocalTime crateTime = trafficPolicyStrategyDTO.getCreateOrderTime().toLocalTime();
        LocalDate crateDate = trafficPolicyStrategyDTO.getCreateOrderTime().toLocalDate();
        int currWeek = LocalDateTimeUtil.dayOfWeek(crateDate).getIso8601Value();
        for (PolicyTimeJsonDTO.PolicyTimeInterval policyTimeInterval : policyTimeJsonDTO) {
            if (currWeek == policyTimeInterval.getWeek()) {
                LocalTime targetStartTime = LocalTime.parse(policyTimeInterval.getStartInterval());
                LocalTime targetEndTime = LocalTime.parse(policyTimeInterval.getEndInterval());
                boolean isInRangeStartTime = (targetStartTime.isBefore(crateTime) || targetStartTime.equals(crateTime)) && targetEndTime.isAfter(crateTime);
                if (isInRangeStartTime) {
                    return true;
                }
            }
        }
        return false;
    }

}
